import datetime
import json
import re

from auto_test.Config import Config
from utils.ApiRequest import ApiRequest
from utils.Common import Common
from utils.DBOper import DBOper
from utils.Log import Log


# 用例工具类
class CaseHanlde:
    def __init__(self, log=None, dbOper=None):
        # db
        if not dbOper:
            self.dbOper = DBOper(**Config.db)
        else:
            self.dbOper = dbOper
        self.dbOper.connect()
        # log
        self.log = log

    def __del__(self):
        self.dbOper.close()

    # 默认的用例运行程序
    def defaultCaseRunning(self, caseConfig, case, isPrintLog=True):
        try:
            if isPrintLog: self.log.info(f'执行：{case["title"]}用例')

            # 如果存在需要替换的模板则替换
            rpList = Common.findReplaceVars(case['headers'])
            headersStr = case['headers']
            if len(rpList):
                rpDict = {}
                for rp in rpList:
                    rpDict[rp] = Config.tempVars[rp]
                    # rpDict[rp] = getattr(Config, rp)
                headersStr = Common.relaceTemplate(headersStr, rpDict)
                if isPrintLog: self.log.info(f'{case["title"]}用例 处理下游headers，最终值：{headersStr}')
            res = ApiRequest.send(
                caseConfig['base_url'] + case['url'],
                method=case['method'],
                data=json.loads(case['request_body']),
                requestType=case['request_type'],
                headers=json.loads(headersStr)
            )
        except Exception as e:
            self.log.error(f'{case["title"]}用例出错：{e}')
            assert False
            return

        # 如果是上游用例则写入值
        try:
            relation = case['relation']
            if relation and len(relation):
                relList = relation.split('=')
                if len(relList[1]) > 0:
                    Config.tempVars[relList[0]] = res['headers'][relList[1]]
                    # setattr(Config, relList[0], res['headers'][relList[1]])
                    if isPrintLog: self.log.info(f'{case["title"]} 用例为上游用例，写入变量：{relList[0]}，值：{res['headers'][relList[1]]}')
        except Exception as e:
            self.log.error(f'{case["title"]}用例出错：{e}')
            assert False
            return

        if isPrintLog: self.log.info(f'结果code：{res['code']}')

        # 断言并将结果写入数据库
        try:
            assert res['code'] == 200
            isPass = True
        except:
            isPass = False
        self.updateResults(case['id'], case['expected'], {"code": res['code']}, isPass)

    # 获取所有用例
    def loadCase(self, web, module=None):
        sql = f'select * from {Config.case['caseTable']} where web = "{web}" and isdel = 0'
        if module:
            sql += f' and module = "{module}"'
        else:
            sql += ';'
        return self.dbOper.read(sql)

    # 加载用例配置
    def loadCaseConfig(self, web, key):
        sql = f"select * from {Config.case['configTable']} where web = '{web}' and key1 = '{key}' and isdel = 0"
        return self.dbOper.read(sql, 'one')

    # 回写存放用例结果        用例id  预期结果   实际结果   是否通过
    def updateResults(self,caseId, expected, response, isPass):
        # 当前时间
        currentTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        sql = (f"insert into {Config.case['resultTable']}(case_id, time, expected, response, is_pass)"
               f"values('{caseId}', '{currentTime}', '{str(expected)}', '{json.dumps(response)}', {isPass})")
        print(sql, 'aaa')
        return self.dbOper.writeOne(sql, autoSubmit=True)
